<template>
  <div style="padding-bottom: 20px; padding-top: 10px;display: flex;">
    <div>
    上传列表
    </div>
    <div style="margin-left: auto;cursor: pointer;" @click="closeRight()"><el-icon><Close /></el-icon></div>
  </div>
  <div>
    <!-- <el-upload
      ref="fileInput"
      action="/javaApi/upload"
      :auto-upload="false"
      :show-file-list="false"
      :on-change="onFileChange"
      multiple
    >
      <el-button slot="trigger">选择文件</el-button>
    </el-upload>
    <el-button @click="uploadFile" :disabled="files.length === 0">上传</el-button> -->
    <div v-for="(item, index) in files" :key="index" class="item">
      <div class="file-name">{{ item.file.name }}</div>
      <el-progress :percentage="item.progress"></el-progress>
    </div>
    <div v-if="files.length==0">  <el-empty description="暂无文件" />
</div>
  </div>
</template>

<script>
import SparkMD5 from "spark-md5";
import axios from "axios";
import { ElUpload, ElButton, ElProgress } from "element-plus";
import { CircleCheck,Close } from "@element-plus/icons-vue";

export default {
  components: {
    ElUpload,
    ElButton,
    ElProgress,
    CircleCheck,Close
  },
  data() {
    return {
      folderId:0,
      files: [], // Array to store uploaded files
      chunkSize: 10 * 1024 * 1024, // 10MB
      uploadUrl: "/javaApi/upload",
      uploadIndex: 0, // Index of the file being uploaded
      isUploading: false, // Flag to track if uploads are in progress
    };
  },
  methods: {
    onFileChange(e, files) {
      // Handle file selection change event
      for (const file of files) {
        const item = {
          file: file.raw,
          progress: 0,
          totalChunks: Math.ceil(file.size / this.chunkSize),
          uploadedChunks: 0,
          uploadToken: null,
        };
        this.files.unshift(item);
      }
      console.log(this.files)
      this.$parent.clearFiles();
      this.startUploadQueue();
    },
    closeRight(){
      this.$parent.closeRight();
    },
    startUploadQueue() {
      // Start the upload queue
      if (!this.isUploading) {
        this.isUploading = true;
        this.uploadIndex = 0;
        this.uploadNextFile();
      }
    },
    async uploadNextFile() {
      // Upload the next file in the queue
      if (this.uploadIndex >= this.files.length) {
        // All files uploaded, stop the upload queue
        this.isUploading = false;
        return;
      }
      const item = this.files[this.uploadIndex];
      if(item.progress==100){
        this.uploadIndex++;
        this.uploadNextFile();
        return;
      }
      const file = item.file;

      // Check if a file is selected
      if (!file) {
        console.log("Please select a file to upload.");
        this.uploadIndex++;
        this.uploadNextFile();
        return;
      }

      // Check if an upload token is available
      if (item.uploadToken === null) {
        // First chunk, create a new upload token
        try {
          let response = await this.createUploadToken(file);
          item.uploadToken = response.uploadToken;
          if (response.isExist === "old") {
            this.finishUpload(item);
            this.uploadIndex++;
            this.uploadNextFile();
            return;
          }
        } catch (error) {
          console.error(error);
          console.log("Failed to create upload token.");
          item.progress = 0;
          this.uploadIndex++;
          this.uploadNextFile();
          return;
        }
      }

      // Calculate chunk data
      const chunkIndex = item.uploadedChunks;
      const start = chunkIndex * this.chunkSize;
      const end = Math.min(start + this.chunkSize, file.size);

      // Read chunk data from the file
      const chunk = file.slice(start, end);
      const reader = new FileReader();
      reader.readAsArrayBuffer(chunk);

      // Compute MD5 hash of the chunk
      const spark = new SparkMD5.ArrayBuffer();
      reader.onload = () => {
        spark.append(reader.result);
        const chunkMD5 = spark.end();

        // Send chunk data to the server
        const formData = new FormData();
        formData.append("chunkIndex", chunkIndex);
        formData.append("chunk", chunk);
        formData.append("chunkMD5", chunkMD5);
        formData.append("totalChunks", item.totalChunks);
        formData.append("uploadToken", item.uploadToken);
        axios
          .post(this.uploadUrl, formData, {
            headers: {
              "Content-Type": "multipart/form-data",
            },
          })
          .then(() => {
            // Update upload progress
            item.uploadedChunks++;
            item.progress = Math.round(
              (item.uploadedChunks / item.totalChunks) * 100
            );

            // Upload next chunk or finish upload
            if (item.uploadedChunks < item.totalChunks) {
              this.uploadNextFile();
            } else {
              this.finishUpload(item);
              this.uploadIndex++;
              this.uploadNextFile();
            }
          })
          .catch((error) => {
            console.error(error);
            console.log("Upload failed.");
            item.progress = 0;
            this.uploadIndex++;
            this.uploadNextFile();
          });
      };
    },
    finishUpload(item) {
      // Method called when upload is completed
      item.progress = 100;
      this.$parent.getPanFilesList();
    },
    async createUploadToken(file) {
      // Method to create an upload token
      const calculateMD5 = async () => {
        // Calculate the file's MD5 hash
        return new Promise((resolve, reject) => {
          const reader = new FileReader();
          reader.onload = () => {
            const spark = new SparkMD5.ArrayBuffer();
            spark.append(reader.result);
            const fileMD5 = spark.end();
            resolve(fileMD5);
          };
          reader.onerror = (error) => {
            reject(error);
          };
          reader.readAsArrayBuffer(file);
        });
      };

      const fileMD5 = await calculateMD5();
      const formData = new FormData();
      const filename = file.name;
      const filesize = file.size;
      console.log(file.size)
      formData.append("name", filename);
      formData.append("fileSize", filesize);
      formData.append("md5", fileMD5);
      formData.append("folderId", this.folderId);

      // Send a request to the server to create a new upload token
      const response = await axios.post(
        this.uploadUrl + "/createUploadToken",
        formData
      );
      return response;
    },
  },
};
</script>
<style scoped>
.file-name{
  word-break: break-all;
}
.item{
  padding: 10px 0px;
  border-bottom: 1px solid #dedede;
}
</style>
